class Bus {
    #eventsObject   // 私有属性 存储各个事件名对应的回调函数数组
    #onceObject     // 私有属性 存储once事件名对应的回调函数数组

    constructor() {
        // 初始化
        this.#eventsObject = {}
        this.#onceObject = {}
    }

    emit(name, ...args) {
        // 拿到对应eventName下的所有回调，依次执行
        let eventCallBackArray = this.#eventsObject[name]
        let onceCallBackArray = this.#onceObject[name]
        eventCallBackArray?.forEach(fn => fn.apply(this, args))
        // once一次便删除
        onceCallBackArray?.forEach(onceFn => onceFn.apply(this, args))
        delete this.#onceObject[name]
    }

    on(name, cb) {
        let eventCallBackArray = this.#eventsObject[name] || []
        eventCallBackArray.push(cb)
        this.#eventsObject[name] = eventCallBackArray
    }

    off(name, cb) {
        // 传了eventName和指定cb则删除对应cb,若没传指定cb则删除所有
        if (cb) {
            this.#eventsObject[name] = this.#eventsObject[name].filter(fn => fn !== cb)
        } else {
            this.#eventsObject[name] = []
        }
    }

    once(name, cb) {
        let onceCallBackArray = this.#onceObject[name] || []
        onceCallBackArray.push(cb)
        this.#onceObject[name] = onceCallBackArray
    }
}

export default new Bus() // 暴露出一个new Bus() 形成单例模式
